﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Controls;
using System.Xml;
using Microsoft.TeamFoundation.Server;
using TFSTools.TFSLibrary;

namespace TFSTools.WpfControls
{
    public abstract class TreeViewItemsBuilder
    {
        public TreeViewItemsBuilder(ITFSConnection connection)
        {
            connection.CheckConnection();

            this.TFSConnection = connection;
            this.ProjectName = connection.SelectedProject.Name;
        }

        protected ITFSConnection TFSConnection { get; set; }

        protected string ProjectName { get; set; }

        public bool IsExpanded { get; set; }

        public abstract void PopulateTreeView(TreeView treeView);
    }

    public abstract class XmlTreeViewItemsBuilder : TreeViewItemsBuilder
    {
        protected abstract string NodeType { get; }

        public XmlTreeViewItemsBuilder(ITFSConnection connection)
            : base(connection)
        {
        }

        public TFSTreeItemFlatList GetFlatList()
        {
            this.TFSConnection.CheckConnection();

            return new TFSTreeItemFlatList(this.TFSConnection.SelectedProject, this.GetNodeInfo(this.NodeType));
        }

        public override void PopulateTreeView(TreeView treeView)
        {
            treeView.Items.Clear();

            // Populate TreeView
            this.BuildTreeViewNodesFromXml(this.NodeType, this.GetNodeInfo(this.NodeType), treeView);
        }

        private XmlElement GetNodeInfo(string nodeType)
        {
            this.TFSConnection.CheckConnection();

            // Retrieve object to get common TFS data
            ICommonStructureService css = this.TFSConnection.SelectedTeamProjectCollection.GetService<ICommonStructureService>();

            // Get Xml Information from TFS
            var projectInfo = css.GetProjectFromName(ProjectName);
            var nodes = css.ListStructures(projectInfo.Uri);
            var nodeInfo = nodes.First(node => node.Name.Contains(nodeType));
            return css.GetNodesXml(new string[] { nodeInfo.Uri }, true);
        }

        private void BuildTreeViewNodesFromXml(string nodeType, XmlElement rootElement, TreeView treeView)
        {
            // Xml Structure for IterationsTree:
            //
            // <Node NodeID="vstfs:///Classification/Node/ec3d6909-c3e2-4d85-83dc-df0fc727b668" Name="Iteration" Path="\TVIS_Home\Iteration" ProjectID="vstfs:///Classification/TeamProject/ee25e5dd-cab3-4c40-ad24-ae2e5b8ce9a1" StructureType="ProjectLifecycle">
            //   <Children>
            //     <Node NodeID="vstfs:///Classification/Node/b0c9ae3b-07fd-41e4-9e2a-0ee77bea038a" Name="Iteration 0" ParentID="vstfs:///Classification/Node/ec3d6909-c3e2-4d85-83dc-df0fc727b668" Path="\TVIS_Home\Iteration\Iteration 0" ProjectID="vstfs:///Classification/TeamProject/ee25e5dd-cab3-4c40-ad24-ae2e5b8ce9a1" StructureType="ProjectLifecycle" /> 
            //     <Node NodeID="vstfs:///Classification/Node/1930e275-62c2-4d8c-b078-df5689bd736f" Name="Iteration 1" ParentID="vstfs:///Classification/Node/ec3d6909-c3e2-4d85-83dc-df0fc727b668" Path="\TVIS_Home\Iteration\Iteration 1" ProjectID="vstfs:///Classification/TeamProject/ee25e5dd-cab3-4c40-ad24-ae2e5b8ce9a1" StructureType="ProjectLifecycle"> 
            //       <Children>
            //         <Node NodeID="vstfs:///Classification/Node/b0c9ae3b-07fd-41e4-9e2a-0ee77bea038a" Name="Iteration 0" ParentID="vstfs:///Classification/Node/ec3d6909-c3e2-4d85-83dc-df0fc727b668" Path="\TVIS_Home\Iteration\Iteration 0" ProjectID="vstfs:///Classification/TeamProject/ee25e5dd-cab3-4c40-ad24-ae2e5b8ce9a1" StructureType="ProjectLifecycle" /> 
            //         <Node NodeID="vstfs:///Classification/Node/1930e275-62c2-4d8c-b078-df5689bd736f" Name="Iteration 1" ParentID="vstfs:///Classification/Node/ec3d6909-c3e2-4d85-83dc-df0fc727b668" Path="\TVIS_Home\Iteration\Iteration 1" ProjectID="vstfs:///Classification/TeamProject/ee25e5dd-cab3-4c40-ad24-ae2e5b8ce9a1" StructureType="ProjectLifecycle" /> 
            //        </Children>
            //     </Node>
            //    </Children>
            // </Node>
            string text = ProjectName;
            TreeViewItem rootNode = new TreeViewItem();
            rootNode.Header = text;
            rootNode.IsExpanded = this.IsExpanded;
            treeView.Items.Add(rootNode);

            XmlNode xmlNode = rootElement.ChildNodes[0];
            if (xmlNode.Name == "Node" && xmlNode.Attributes["Name"].Value == nodeType && xmlNode.HasChildNodes)
            {
                foreach (XmlNode childrenNode in xmlNode.ChildNodes)
                {
                    if (childrenNode.Name == "Children" && childrenNode.HasChildNodes)
                    {
                        foreach (XmlNode childNode in childrenNode.ChildNodes)
                        {
                            if (xmlNode.Name == "Node")
                            {
                                this.AddTreeViewNodes(rootNode.Items, childNode);
                            }
                        }
                    }
                }
            }
        }

        private void AddTreeViewNodes(ItemCollection treeNodeItems, XmlNode xmlNode)
        {
            string text = xmlNode.Attributes["Name"].Value;
            
            TreeViewItem newNode = new TreeViewItem()
            {
                Header = text,
                IsExpanded = IsExpanded
            };

            treeNodeItems.Add(newNode);

            if (xmlNode.HasChildNodes)
            {
                foreach (XmlNode childrenNode in xmlNode.ChildNodes)
                {
                    if (childrenNode.Name == "Children" && xmlNode.HasChildNodes)
                    {
                        foreach (XmlNode childNode in childrenNode.ChildNodes)
                        {
                            if (xmlNode.Name == "Node")
                            {
                                this.AddTreeViewNodes(newNode.Items, childNode);
                            }
                        }
                    }
                }
            }
        }
    }
}
